package com.zmzncs.lmtc.module.shop.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.zmzncs.lmtc.common.pojo.LoginUser;
import com.zmzncs.lmtc.common.pojo.Rest;
import com.zmzncs.lmtc.common.util.*;
import com.zmzncs.lmtc.module.customer.dao.CustTicketDao;
import com.zmzncs.lmtc.module.customer.dao.CustomerDao;
import com.zmzncs.lmtc.module.customer.pojo.customer.CustomerDTO;
import com.zmzncs.lmtc.module.customer.pojo.ticket.CustTicket;
import com.zmzncs.lmtc.module.shop.dao.ShopGoodsMapper;
import com.zmzncs.lmtc.module.shop.dao.ShopInfoMapper;
import com.zmzncs.lmtc.module.shop.pojo.shop_goods.ShopGoods;
import com.zmzncs.lmtc.module.shop.pojo.shop_info.ShopInfo;
import com.zmzncs.lmtc.module.shop.pojo.shop_order.GoodsBuyForm;
import com.zmzncs.lmtc.module.shop.pojo.shop_order.ShopOrder;
import com.zmzncs.lmtc.module.shop.dao.ShopOrderMapper;
import com.zmzncs.lmtc.module.shop.pojo.shop_order.ShopOrderDTO;
import com.zmzncs.lmtc.module.shop.pojo.shop_order.ShopOrderGoodsDTO;
import com.zmzncs.lmtc.module.shop.service.ShopOrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

import static com.zmzncs.lmtc.common.util.WeChatUtil.payTest;

/**
 * <p>
 * 商户-订单 服务实现类
 * </p>
 *
 * @author 高博文
 * @since 2021-05-20
 */
@Service
public class ShopOrderServiceImpl extends ServiceImpl<ShopOrderMapper, ShopOrder> implements ShopOrderService {

    @Autowired
    ShopOrderMapper shopOrderMapper;
    @Autowired
    CustomerDao customerDao;
    @Autowired
    CustTicketDao custTicketDao;
    @Autowired
    ShopGoodsMapper shopGoodsMapper;
    @Autowired
    ShopInfoMapper shopInfoMapper;

    @Autowired
    HttpServletRequest request;

    @Value("${wechat.notify-url.buyGoods}")
    String buyGoodsNotifyUrl;

    @Value("${pay-test}")
    boolean payTest;


    @Override
    public Map<String, Object> buyGoods(GoodsBuyForm form) {
        //购买数量
        Integer quantity = form.getQuantity();

        ShopGoods shopGoods = shopGoodsMapper.selectById(form.getGoodsId());
        if (shopGoods == null) {
            ExceptionUtil.businessException("商品：" + form.getGoodsId() + "不存在");
        }
        if (shopGoods.getStock() - quantity < 0) {
            ExceptionUtil.businessException("商品库存不够！");
        }

        //支付金额
        BigDecimal paidAmount = form.getPaidAmount();

        CustTicket ticket = custTicketDao.selectById(form.getCustTicketId());
        //校验支付金额
        checkPaidAmount(form.getPaidAmount(), shopGoods.getSellPrice().multiply(new BigDecimal(quantity)), ticket);

        LoginUser loginUser = JwtUtil.getLoginUser(request);
        //  查询客户
        CustomerDTO customerDTO = customerDao.getCustomerById(loginUser.getCustomerId());
        if (customerDTO == null) {
            ExceptionUtil.businessException("客户：" + loginUser.getCustomerId() + "不存在");
        }
        if (StringUtils.isBlank(customerDTO.getMobilePhone())) {
            ExceptionUtil.businessException("请绑定手机号");
        }

        ShopInfo shopInfo = shopInfoMapper.selectById(form.getShopId());
        if (shopInfo == null) {
            ExceptionUtil.businessException("商户：" + form.getShopId() + "不存在");
        }

        //平台金额
        BigDecimal platformAmount = form.getPaidAmount().multiply(shopInfo.getPlatformDivide().divide(new BigDecimal(100)));
        //车场金额
        BigDecimal parkAmount = platformAmount.multiply(shopInfo.getParkDivide().divide(new BigDecimal(100)));
        //商户金额
        BigDecimal shopAmount = form.getPaidAmount().subtract(platformAmount);
//        ShopOrderDTO shopOrderDTO = shopOrderMapper.getWaitPayOrderByGoodsId(customerDTO.getId() , form.getGoodsId());
        //  订单号
        String orderCode = ChinaumsUtil.getMerOrderId("SG");
        ShopOrder order = new ShopOrder();
        String writeOffCode = ChinaumsUtil.getWriteOffCode();
        order.setOrderCode(orderCode);
        order.setCustomerId(customerDTO.getId());
        order.setShopId(shopInfo.getId());
        order.setGoodsId(form.getGoodsId());
        order.setQuantity(quantity);
        if (ticket != null) {
            order.setCustTicketId(ticket.getId());
        }
        order.setPayableAmount(form.getPayableAmount());
        order.setPaidAmount(form.getPaidAmount());
        order.setWriteOffCode(writeOffCode);
        order.setPlatformDivide(shopInfo.getPlatformDivide());
        order.setParkDivide(shopInfo.getParkDivide());
        order.setPaidPlatformAmount(platformAmount);
        order.setPaidParkAmount(parkAmount);
        order.setPaidShopAmount(shopAmount);
        order.setPayStatus(0);
        order.setIsWriteOff(0);
        order.setIsPaidToPark(0);
        order.setIsPaidToShop(0);

        shopOrderMapper.insert(order);

        JSONObject attach = new JSONObject();
        attach.put("custTicketId", form.getCustTicketId());
        attach.put("orderCode", orderCode);
        attach.put("quantity", quantity);
        //  如果支付金额为0，则不走微信支付
        if (paidAmount.compareTo(new BigDecimal(0)) <= 0) {
            //处理购买的商品
            buyGoodsCallbackHandle(orderCode, attach.toJSONString());
            return null;
        } else {
            //  测试环境金额
            paidAmount = payTest ? new BigDecimal("0.01") : paidAmount;    //  支付金额
            return WeChatUtil.wxPay(customerDTO.getOpenid(), buyGoodsNotifyUrl, paidAmount, orderCode, attach.toJSONString(), "购买商品");
        }
    }

    @Override
    public String buyGoodsCallback(String callbackStr) {
        //  解析微信返回值
        Map<String, String> callbackMap = null;
        try {
            callbackMap = XmlUtil.parseXML(callbackStr);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 支付成功
        if ("SUCCESS".equals(callbackMap.get("return_code")) && "SUCCESS".equals(callbackMap.get("result_code"))) {
            String orderCode = callbackMap.get("out_trade_no");    //  订单号

            String attach = callbackMap.get("attach");  //  附加数据
            attach = StringEscapeUtils.unescapeJava(attach);
            JSONObject attachJB = JSONObject.parseObject(attach);
            String custTicketId = attachJB == null ? null : attachJB.getString("custTicketId");
            String quantity = attachJB == null ? null : attachJB.getString("quantity");
            //String orderCode = callbackMap.get("orderCode");

            //根据订单编号查询商户订单信息
            ShopOrderDTO shopOrderDTO = shopOrderMapper.getOrderByOrderCode(orderCode);
            if (shopOrderDTO == null) {
                ExceptionUtil.businessException("用户订单不存在，orderCode：" + orderCode);
            }
            ShopGoods shopGoods = shopGoodsMapper.selectById(shopOrderDTO.getGoodsId());
            if (shopGoods == null) {
                ExceptionUtil.businessException("商品：" + shopOrderDTO.getGoodsId() + "不存在");
            }

            ShopOrder shopOrder = new ShopOrder();
            shopOrder.setId(shopOrderDTO.getId());
            shopOrder.setPayStatus(1);
            shopOrder.setPayTime(new Date());
            shopOrderMapper.updateById(shopOrder);

            if (StringUtils.isNotBlank(quantity)
                    && shopGoods.getStock() - Integer.valueOf(quantity) >= 0) {
                Integer stock = shopGoods.getStock() - Integer.valueOf(quantity);
                shopGoods.setStock(stock <= 0 ? 0 : stock);
                shopGoodsMapper.updateById(shopGoods);
            }

            if (StringUtils.isNotBlank(custTicketId)) {
                CustTicket ticket = custTicketDao.selectById(Long.valueOf(custTicketId));
                if (ticket == null) {
                    ExceptionUtil.businessException("用户优惠券不存在，ticketId：" + custTicketId);
                }
                ticket.setStatus(1);
                custTicketDao.updateById(ticket);
            }
        }
        return WeChatUtil.wxpayCallbackResult(true);
    }

    /**
     * 直接返回二维码暂无具体方法
     */
    @Override
    public String useGoods(Long id) {
        ShopOrder shopOrder = shopOrderMapper.selectById(id);
        if (shopOrder == null
                || shopOrder.getIsWriteOff() == 1
                || StringUtils.isBlank(shopOrder.getWriteOffCode())) {
            ExceptionUtil.businessException("商品有误");
            return "";
        }
        return shopOrder.getWriteOffCode();
    }

    @Override
    public Rest refundGoods(Long id) {
        ShopOrder shopOrder = shopOrderMapper.selectById(id);
        if (shopOrder == null) {
            ExceptionUtil.businessException("商品有误");
            return RestUtil.error("商品有误，退款失败！");
        }
        if (shopOrder.getIsWriteOff() == 1 || shopOrder.getPayStatus().intValue() != 1) {
            ExceptionUtil.businessException("商品状态有误");
            return RestUtil.error("商品状态有误，退款失败！");
        }
        String tradeNo = WeChatUtil.generateTradeNo();
        Map result = WeChatUtil.refund(tradeNo, shopOrder.getPaidAmount(), shopOrder.getPaidAmount(), shopOrder.getOrderCode(), "商品退款");
        if (result != null && result.get("resultCode").equals("SUCCESS")) {
            shopOrder.setPayStatus(4);//已退款
            shopOrder.setRefundTime(new Date());
            shopOrderMapper.updateById(shopOrder);
            return RestUtil.success();
        } else {
            ExceptionUtil.businessException("商品退款失败");
            return RestUtil.error("商品退款失败！");
        }
    }

    /**
     * 根据状态 查商户订单信息
     */
    @Override
    public List<ShopOrderGoodsDTO> getMyOrderInfoListByStatus(Long customerId, Long status) {
        return shopOrderMapper.getMyOrderInfoListByStatus(customerId, status);
    }

    /**
     * 校验支付金额
     *
     * @param paidAmount     实付金额
     * @param payAbleAmount 应付金额
     * @param ticket         优惠券
     */
    void checkPaidAmount(BigDecimal paidAmount, BigDecimal payAbleAmount, CustTicket ticket) {
        //  应收金额
        BigDecimal receivableAmount = new BigDecimal(0);
        if (ticket != null) {
            //  减免金额
            if (ticket.getPreferentialType().equals(1)) {
                //  应付金额
                receivableAmount = payAbleAmount.subtract(ticket.getPreferentialMoney());
            }
            //  折扣
            if (ticket.getPreferentialType().equals(2)) {
                //  折扣金额
                BigDecimal preferentialMoney = payAbleAmount.multiply(ticket.getDiscountRate());
                //  应付金额
                receivableAmount = payAbleAmount.subtract(preferentialMoney);
            }

            if (receivableAmount.compareTo(new BigDecimal(0)) > 0 && receivableAmount.compareTo(paidAmount) != 0) {
                ExceptionUtil.businessException("金额不正确");
            }
        } else if (paidAmount.compareTo(payAbleAmount) != 0) {
            ExceptionUtil.businessException("金额不正确");
        }
    }

    /**
     * 处理购买的商品
     */
    @Transactional
    public String buyGoodsCallbackHandle(String orderCode, String attach) {

        JSONObject attachJB = JSONObject.parseObject(attach);
        String custTicketId = attachJB.getString("custTicketId");
        String quantity = attachJB.getString("quantity");
        //根据订单编号查询商户订单信息
        ShopOrderDTO shopOrderDTO = shopOrderMapper.getOrderByOrderCode(orderCode);
        if (shopOrderDTO == null) {
            ExceptionUtil.businessException("用户订单不存在，orderCode：" + orderCode);
        }
        ShopOrder shopOrder = new ShopOrder();
        shopOrder.setId(shopOrderDTO.getId());
        shopOrder.setPayStatus(1);
        shopOrderMapper.updateById(shopOrder);

        ShopGoods shopGoods = shopGoodsMapper.selectById(shopOrderDTO.getGoodsId());
        if (shopGoods == null) {
            ExceptionUtil.businessException("商品：" + shopOrderDTO.getGoodsId() + "不存在");
        }
        if (StringUtils.isNotBlank(quantity) && (shopGoods.getStock() - Integer.valueOf(quantity)) < 0) {
            ExceptionUtil.businessException("商品库存不够！");
        }

        CustTicket custTicket = null;
        if (StringUtils.isNotBlank(custTicketId)) {
            custTicket = custTicketDao.selectById(Long.parseLong(custTicketId));
            if (custTicket == null) {
                ExceptionUtil.businessException("用户优惠券不存在，ticketId：" + custTicketId);
            }
            custTicket.setStatus(1);
            custTicket.setTipsStatus(0);
            custTicket.setUpdateTime(new Date());
            custTicketDao.updateById(custTicket);
        }
        return "SUCCESS";
    }

}
